package flexo.examples;

import flexo.input.Event;
import flexo.math.Matrix;
import flexo.math.Quaternion;
import flexo.math.Vector;
import flexo.physic.force.SimpleForce;

public class Test_Physic_SimpleCollision extends Test_Graphic_Base implements flexo.input.EventListener
{
	class Ball
	{
		public flexo.scene.Node ballNode;
		public flexo.scene.Node shadowNode;	
		public flexo.physic.entity.Entity ballPhysics;
	}
	
	Ball[] balls;
	
	flexo.scene.Node root;
	flexo.scene.Node gridNode;
	
	public static final int NUM_BALLS = 6;	
	public static float SPEED = 14;
	
	SimpleForce[] sf;
		
	public static void main(String[] args)
	{
		run("flexo.examples.Test_Physic_SimpleCollision");
	}
	
	public void init()
	{
		super.init();
		
		root = mainScene.addChild("root");
		gridNode = root.addChild("grid");	
		
		// Grid
		
		flexo.graphic.Material mat = graphic.addMaterial("gridMat", "textureRepeat");
		flexo.graphic.ShaderParam param = mat.getShaderParam("tex");
		param.setValue("textures/blocks.jpg");
		param = mat.getShaderParam("repeatU");
		param.setValue(10.0f);
		param = mat.getShaderParam("repeatV");
		param.setValue(10.0f);
		
		flexo.graphic.entity.Entity grid = graphic.addQuad(20, 20);
		grid.setMaterial("gridMat");
		grid.attachTo(gridNode);
		gridNode.setRotation(new flexo.math.Quaternion(new flexo.math.Vector(1,0,0),-90.0f));
		gridNode.setPosition(new flexo.math.Vector(0,-0.55,0));
		
		// Ball
		
		mat = graphic.addMaterial("billMat", "billboard");
		mat.setBlending(flexo.graphic.Material.Blending.TRANSPARENT_MASK);
		param = mat.getShaderParam("tex");
		param.setValue("textures/beachball.png");
				
		flexo.graphic.entity.Entity billboard = graphic.addQuad(1, 1);
		billboard.setMaterial("billMat");
		
		// Shadow		
		mat = graphic.addMaterial("shadowMat", "default");
		mat.setBlending(flexo.graphic.Material.Blending.TRANSPARENT_MULTIPLY);
		param = mat.getShaderParam("tex");
		param.setValue("textures/dotshadow.jpg");
		
		flexo.graphic.entity.Entity shadow = graphic.addQuad(1, 1);
		shadow.setMaterial("shadowMat");		
		
		// CREATING ALL BALLS
		
		balls = new Ball[NUM_BALLS];
		
		flexo.math.Random random = new flexo.math.Random();
		
		for (int i = 0; i < NUM_BALLS; ++i)
		{
			Ball b = new Ball();
			b.ballNode = mainScene.addChild("ball"+i);
			billboard.attachTo(b.ballNode);
			
			b.shadowNode = b.ballNode.addChild("shadow"+i);
			b.shadowNode.setPosition(new Vector(0,-0.5,0));
			shadow.attachTo(b.shadowNode);
			b.shadowNode.setRotation(new flexo.math.Quaternion(new flexo.math.Vector(1,0,0),-90.0f));
			
			b.ballPhysics = physics.addSphere(1,1);
			b.ballPhysics.setGravity(0);
			b.ballPhysics.setDamping(0.1f);
			b.ballPhysics.attachTo(b.ballNode);
			
			if (i > 0)
			{
				float x = (random.nextFloat() * 20) - 10;
				float z = (random.nextFloat() * 20) - 10;
				b.ballPhysics.setPosition(new Vector(x,0,z));
			}
			
			balls[i] = b;
		}			
		
		sf = new SimpleForce[4];
		sf[0] = physics.addSimpleForce("fMoveForward", new Vector(0,0,-1));
		sf[1] = physics.addSimpleForce("fMoveBackward", new Vector(0,0,1));
		sf[2] = physics.addSimpleForce("fMoveLeft", new Vector(-1,0,0));
		sf[3] = physics.addSimpleForce("fMoveRight", new Vector(1,0,0));			
		
		// MOVEMENT
		balls[0].ballPhysics.applyForce("fMoveForward");
		balls[0].ballPhysics.applyForce("fMoveBackward");
		balls[0].ballPhysics.applyForce("fMoveLeft");
		balls[0].ballPhysics.applyForce("fMoveRight");
				
		input.addAction("ballForward", flexo.input.EventType.KEY_I);
		input.addAction("ballBackward", flexo.input.EventType.KEY_K);
		input.addAction("ballLeft", flexo.input.EventType.KEY_J);
		input.addAction("ballRight", flexo.input.EventType.KEY_L);
		
		input.addEventListener(this);
		
		this.camPosNode.setPosition(new Vector(0,2,6));
	}

	public void cleanUp()
	{
	}	

	public void update()
	{
	}

	@Override
	public void processEvent(Event e)
	{
		if (e.check("ballForward"))
		{
			if (e.getValue() > 0)
			{
				sf[0].setMagnitude(SPEED);
			}
			else
			{
				sf[0].setMagnitude(0);
			}
		}
		else if (e.check("ballBackward"))
		{
			if (e.getValue() > 0)
			{
				sf[1].setMagnitude(SPEED);
			}
			else
			{
				sf[1].setMagnitude(0);
			}
		}
		else if (e.check("ballLeft"))
		{
			if (e.getValue() > 0)
			{
				sf[2].setMagnitude(SPEED);
			}
			else
			{
				sf[2].setMagnitude(0);
			}
		}
		else if (e.check("ballRight"))
		{
			if (e.getValue() > 0)
			{
				sf[3].setMagnitude(SPEED);
			}
			else
			{
				sf[3].setMagnitude(0);
			}
		}
	}
}
